use super::container::{ContainerId,ContainerStore};

use super::util::*;

use crate::container::ContainerResult;
use crate::rechunk::ReChunk;
use crate::constants::DefaultFingerprintType;
use std::sync::Arc;


pub trait ChunkPointer {
	//type Index = u32;
	fn new(id:ContainerId,index:u32,chunk:&DefaultFingerprintType) -> Self where Self:Sized;
	fn containerid(&self) -> ContainerId;
	fn no(&self) -> u32;
	fn as_raw_data(&self) -> &[u8];
	fn as_raw_mut(&mut self) -> &mut [u8];
	fn read(&self,c:&ContainerStore) -> ContainerResult<Arc<ReChunk>>;
	fn read_exact(&self,c:&ContainerStore) -> ContainerResult<Arc<ReChunk>>;
	//fn in_store(&self,c:&ContainerStore) -> Option<Arc<ReChunk>>;
}

#[derive(RawData,Debug)]
pub struct IndexPointer {
	id:ContainerId,
	no:u32,
}

impl ChunkPointer for IndexPointer {
	//type Index = u32;
	fn new(id:ContainerId,index:u32,_:&DefaultFingerprintType) -> Self {
		Self {
			id:id,
			no:index,
		}
	}
	
	fn containerid(&self) -> ContainerId {
		self.id
	}

	fn no(&self) -> u32 {
		self.no
	}
	
	fn as_raw_data(&self) -> &[u8] {
		self.as_raw_data()
	}
	
	fn as_raw_mut(&mut self) -> &mut [u8] {
		self.as_raw_mut()
	}
	
	fn read(&self,c:&ContainerStore) -> ContainerResult<Arc<ReChunk>> {
		c.read_container(self.id).map(|c|c.get(self.no))
	}

	fn read_exact(&self,c:&ContainerStore) -> ContainerResult<Arc<ReChunk>> {
		c.read_container(self.id).map(|c|c.get(self.no))
	}
}



